home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / cross.com / CROSS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-23  |  30.6 KB  |  889 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /*    CROSS  -  A 'C' Cross refernce Utility               */
  4. /*                                                         */
  5. /*    Version 1.0   January, 1982                          */
  6. /*                                                         */
  7. /*    Copyright (c) 1982 by Philip N. Hisley               */
  8. /*                                                         */
  9. /*    Released for non-commercial distribution only        */
  10. /*                                                         */
  11. /*    Abstract:                                            */
  12. /*                                                         */
  13. /*    'CROSS' is a cross-reference utility for 'C' programs*/
  14. /*    Its has the ability to handle nested include files   */
  15. /*    to a depth of 8 levels and properly processes nested */
  16. /*    comments as supported by BDS C. Option flags support */
  17. /*    the following features:                              */
  18. /*                                                         */
  19. /*    - Routing of list output to disk                     */
  20. /*    - Cross-referencing of reserved words                */
  21. /*    - Processing of nested include files                 */
  22. /*    - Generation of listing only                         */
  23. /*                                                         */
  24. /*    Usage: cross  <flag(s)> <filename>                   */
  25. /*                                                         */
  26. /*    Flags: -i            = Enable file inclusion         */
  27. /*           -c            = Cross reference only          */
  28. /*           -l            = Generate listing only         */
  29. /*           -p            = Reset page size (Def:60)      */
  30. /*           -r            = Cross-ref reserved words      */
  31. /*           -o<filename>  = Write output to named file    */
  32. /*                                                         */
  33. /*    -------------------------------------------------    */
  34. /*                                                         */
  35. /*    Modified for Lattice 'C' Version 1.01                */
  36. /*    By: John W. Kindschi Jr.  16 Nov 1983                */
  37. /*                                                         */
  38. /*                                                         */
  39. /*    Modified for Turbo 'C' and Unix                      */
  40. /*    Added -c option for references only                  */
  41. /*    Fixed -i option - no abort if not found              */
  42. /*    Rebuilt command line interpreter                     */
  43. /*    Print message when include file not found            */
  44. /*    Default output to a.crf                              */
  45. /*    Allowed variable page size settings                  */
  46. /*                                                         */
  47. /*    By: Patrick L. McGillan   July, 1987                 */
  48. /*                                                         */
  49. /*    -------------------------------------------------    */
  50. /*                                                         */
  51. /*    Modified to allow multiple cross refrenced           */
  52. /*    files on the command lines.                          */
  53. /*                                                         */
  54. /*    By: Patrick L. McGillan    Nov, 1990                 */
  55. /*                                                         */
  56. /*    -------------------------------------------------    */
  57. /*                                                         */
  58. /*    Please report bugs/fixes/enhancements to:            */
  59. /*                                                         */
  60. /*            Philip N. Hisley                             */
  61. /*            548H Jamestown Court                         */
  62. /*            Edgewood, Maryland 21040                     */
  63. /*            (301) 679-4606                               */
  64. /*            Net Addr: PNH@MIT-AI                         */
  65. /*                                                         */
  66. /*                                                         */
  67. /***********************************************************/
  68.  
  69. #include "stdio.h"
  70. #include "ctype.h"
  71.  
  72. #define TRUE 1
  73. #define FALSE 0
  74. #define ERROR -1
  75. #define CPMEOF 0x1a
  76. #define MAX_REF    5           /* maximum refs per ref-block */
  77. #define MAX_LEN    20          /* maximum identifier length  */
  78. #define MAX_WRD  1000          /* maximum number of identifiers */
  79. #define MAX_ALPHA  53          /* maximum alpha chain heads */
  80. #define REFS_PER_LINE  8       /* maximum refs per line */
  81. #define LINES_PER_PAGE 60
  82. #define FF 0x0C                 /* formfeed */
  83.  
  84. struct  rf_blk {
  85.         int  ref_item[MAX_REF];
  86.         int  ref_cnt;
  87. onerf;
  88.  
  89. struct  id_blk {
  90.         char  id_name[MAX_LEN];
  91.         struct id_blk *alpha_lnk;
  92.         struct rf_blk *top_lnk;
  93.         struct rf_blk *lst_lnk;
  94. oneid;
  95.  
  96. struct id_blk *id_vector[MAX_WRD];
  97.  
  98. struct alpha_hdr { 
  99.         struct id_blk *alpha_top;
  100.         struct id_blk *alpha_lst;
  101. };
  102.  
  103. struct alpha_hdr alpha_vector[MAX_ALPHA];
  104.  
  105. int     linum;          /* line number                  */
  106. int     edtnum;         /* edit line number             */
  107. int     fil_cnt;        /* active file index            */
  108. int     wrd_cnt;        /* token count                  */
  109. int     pagno;          /* page number                  */
  110. int     id_cnt;         /* number of unique identifiers */
  111. int     rhsh_cnt;       /* number of conflict hits      */
  112. int     filevl;         /* file level                   */
  113. int     paglin;         /* page line counter            */
  114. int     paglen;         /* length of a page             */
  115. int     prt_ref;
  116. char    act_fil[MAX_LEN];
  117. char    lst_fil[MAX_LEN];
  118. char    gbl_fil[MAX_LEN];
  119. FILE    *l_buffer;
  120.  
  121. int     i_flg,o_flg,r_flg,l_flg,c_flg;
  122.  
  123. main (argc,argv)
  124. int     argc;
  125. char    *argv[];
  126.  
  127. {
  128.         char  flag;
  129.         register int carg;
  130.  
  131.         if (argc < 2) use_err();
  132.  
  133.         c_flg = i_flg = r_flg = o_flg = l_flg = FALSE;
  134.  
  135.         for (carg = 1; carg < argc; ++carg) {
  136.                 if (argv[carg][0] == '-') {     /* if its a switch, process it */
  137.                         switch (argv[carg][1]) {
  138.                                 case 'c':
  139.                                 case 'C': c_flg++;
  140.                                           break;
  141.                                 case 'i':
  142.                                 case 'I': i_flg++;
  143.                                           break;
  144.                                 case 'l':
  145.                                 case 'L': l_flg++;
  146.                                           break;
  147.                                 case 'o': 
  148.                                 case 'O': o_flg++;
  149.                                           if (argv[carg][2] == 0) use_err();
  150.                                           strcpy (lst_fil, &argv[carg][2]);
  151.                                           break;
  152.                                 case 'p':
  153.                                 case 'P': strcpy (act_fil, &argv[carg][2]);
  154.                                           paglen = atoi(act_fil);
  155.                                           break;
  156.                                 case 'r':
  157.                                 case 'R': r_flg++;
  158.                                           break;
  159.                                 default : use_err();
  160.                         }
  161.                 } else break;
  162.         }
  163.  
  164.         if (paglen < 10) paglen = LINES_PER_PAGE;
  165.  
  166.         if (!o_flg) {
  167.                 o_flg++;
  168.                 strcpy (lst_fil, "a.crf");
  169.         }
  170.  
  171.         if (o_flg) {
  172.                 if ((l_buffer=fopen(lst_fil,"w"))==NULL) { 
  173.                         printf("ERROR: Unable to create list file - %s\n",lst_fil);
  174.                         exit(0);
  175.                 }
  176.                 printf ("\n\nCROSS ... 'C' Cross Reference Utility  v1.0\n\n");
  177.                 printf ("Output is in file: %s\n\n", lst_fil);
  178.         }
  179.  
  180.         prt_ref = FALSE;
  181.  
  182.         for(linum=0;linum < MAX_WRD;linum++) {
  183.                 id_vector[linum] = NULL; 
  184.         }
  185.  
  186.         for(linum=0;linum < MAX_ALPHA;linum++)
  187.                 alpha_vector[linum].alpha_top = alpha_vector[linum].alpha_lst = NULL;
  188.  
  189.         fil_cnt = wrd_cnt = 0;
  190.  
  191.         filevl = paglin = pagno = 0;
  192.  
  193.         if (c_flg) linum = edtnum = 1;
  194.         else linum = edtnum = 0;
  195.  
  196.         id_cnt = rhsh_cnt = 0;
  197.  
  198.         do {
  199.             strcpy (gbl_fil, argv[carg]);
  200.             proc_file (gbl_fil);
  201.         } while (++carg<argc);
  202.  
  203.         if (!l_flg) {
  204.                 prnt_tbl ();
  205.                 printf ("\nAllowable Symbols: %d\n",MAX_WRD);
  206.                 printf ("Unique    Symbols: %d\n",id_cnt);
  207.         }
  208.  
  209.         if (o_flg) {
  210.                 nl ();
  211.                 fprintf (l_buffer,"%c",CPMEOF);
  212.                 fflush (l_buffer);
  213.                 fclose (l_buffer);
  214.         }
  215. }
  216.  
  217.  
  218.  
  219. use_err()
  220.         printf("\n\n\007");
  221.         printf("Usage: cross <flag(s)> <filename>\n\n");
  222.         printf("Flags: -i            = Enable file inclusion\n");
  223.         printf("       -c            = Cross reference only\n");
  224.         printf("       -l            = Generate listing only\n");
  225.         printf("       -o<filename>  = Write output to named file\n");
  226.         printf("       -p<n>         = Change length of page (Def:60)\n");
  227.         printf("       -r            = Cross-reference reserved words\n");
  228.         exit(0); 
  229. }
  230.  
  231. proc_file(filnam)
  232. char    *filnam;
  233. {
  234.         FILE  *buffer;        /* allocated buffer pointer */
  235.         char  token[MAX_LEN]; /* token buffer */
  236.         int   eof_flg;        /* end-of-file indicator */
  237.         int   tok_len;        /* token length */
  238.         int   incnum;         /* included line number */
  239.         strcpy(act_fil,filnam);
  240.         if((buffer=fopen(filnam,"r"))==NULL)
  241.         {
  242.                 printf ("\nERROR: Unable to open input file: %s\n",filnam);
  243.                 fprintf (l_buffer, "\nERROR: Unable to open input file: %s",filnam);
  244.                 if (incnum)
  245.                         return;
  246.                 exit(0);
  247.         }
  248.         if ((filevl++ == 0) && (!c_flg))
  249.                 prt_hdr();
  250.         eof_flg = FALSE;
  251.         do { 
  252.                 if(get_token(buffer,token,&tok_len,&eof_flg,0))
  253.                         if(chk_token(token))
  254.                         {
  255.                                 if(strcmp(token,"#include") == 0) 
  256.                                         if(get_token(buffer,token,&tok_len,&eof_flg,1))
  257.                                                 if(!i_flg) continue;
  258.                                 else
  259.                                     { 
  260.                                         incnum=edtnum;
  261.                                         edtnum=0;
  262.                                         if (!c_flg)
  263.                                                 nl();
  264.                                         proc_file(token); 
  265.                                         edtnum=incnum;
  266.                                         strcpy(act_fil,filnam);
  267.                                         continue;
  268.                                 }
  269.                                 put_token(token,linum);
  270.                         }
  271.         } 
  272.         while (!eof_flg);
  273.  
  274.         filevl -= 1;
  275.         fclose(buffer);
  276. }
  277.  
  278. get_token(g_buffer,g_token,g_toklen,g_eoflg,g_flg)
  279.  
  280. FILE    *g_buffer;
  281. char    *g_token;
  282. int     *g_toklen;
  283. int     *g_eoflg;
  284. int     g_flg;
  285.  
  286. /*
  287.         'getoken' returns the next valid identifier or
  288.         reserved word from a given file along with the
  289.         character length of the token and an end-of-file
  290.         indicator
  291. */
  292.  
  293. {
  294.         int     c;
  295.         char    *h_token;
  296.         char    tmpchr;
  297.  
  298.         h_token = g_token;
  299.  
  300. gtk:
  301.         *g_toklen = 0;
  302.         g_token = h_token;
  303.  
  304.         /* Scan and discard any characters until an alphabetic or
  305.            '_' (underscore) character is encountered or an end-of-file
  306.            condition occurs        */
  307.  
  308.         while((!isalpha(*g_token = rdchr(g_buffer,g_eoflg,g_flg))) && !*g_eoflg
  309.             && *g_token != '_' && *g_token != '0' && *g_token != '#');
  310.         if(*g_eoflg) return(FALSE);
  311.         *g_toklen += 1;
  312.  
  313.         /*    Scan and collect identified alpanumeric token until
  314.               a non-alphanumeric character is encountered or and
  315.               end-of-file condition occurs              */
  316.  
  317.         if(g_flg) tmpchr = '.';
  318.         else tmpchr = '_';
  319.         while((isalpha(c=rdchr(g_buffer,g_eoflg,g_flg)) ||
  320.             isdigit(c) || c == '_' || c == tmpchr) && !*g_eoflg)
  321.         { 
  322.                 if(*g_toklen < MAX_LEN)
  323.                 { 
  324.                         *++g_token = c;
  325.                         *g_toklen += 1; 
  326.                 }
  327.         }
  328.  
  329.         /*   Check to see if a numeric hex or octal constant has
  330.              been encountered ... if so dump it and try again     */
  331.  
  332.         if (*h_token == '0') goto gtk;
  333.  
  334.  
  335.         /*
  336.                                 Tack a NULL character onto the end of the token
  337.                         */
  338.  
  339.         *++g_token = NULL;
  340.  
  341.         /*
  342.                                 Screen out all #token strings except #include
  343.                         */
  344.  
  345.         if (*h_token == '#' && strcmp(h_token,"#include")) goto gtk;
  346.  
  347.         return(TRUE);
  348. }
  349.  
  350. fil_chr(f_buffer,f_eof)
  351. FILE *f_buffer;
  352. int *f_eof;
  353.         int fc;
  354.         fc=getc(f_buffer);
  355.         if (fc == CPMEOF || fc == EOF) { 
  356.                 *f_eof = TRUE;
  357.                 fc = NULL; 
  358.         }
  359.         return(fc);
  360. }
  361.  
  362. /***************************************************************************
  363.  *       'rdchr' returns the next valid character in a file
  364.  *       and an end-of-file indicator. A valid character is
  365.  *       defined as any which does not appear in either a
  366.  *       commented or a quoted string ... 'rdchr' will correctly
  367.  *       handle comment tokens which appear within a quoted
  368.  *       string
  369.  */
  370.  
  371. rdchr(r_buffer,r_eoflg,rd_flg)
  372. int     *r_eoflg;
  373. FILE    *r_buffer;
  374. int     rd_flg;
  375. {
  376.         int     c;
  377.         int     q_flg;          /* double quoted string flag */
  378.         int     q1_flg;         /* single quoted string flag */
  379.         int     cs_flg;         /* comment start flag */
  380.         int     ce_flg;         /* comment end flag */
  381.         int     c_cnt;          /* comment nesting level */
  382.         int     t_flg;          /* transparency flag */
  383.  
  384.         q_flg = FALSE;
  385.         q1_flg = FALSE;
  386.         cs_flg = FALSE;
  387.         ce_flg = FALSE;
  388.         t_flg = FALSE;
  389.         c_cnt  = 0;
  390. rch:    c=fil_chr(r_buffer,r_eoflg);            /* Fetch character from file */
  391.         if(*r_eoflg)                            /* EOF encountered */
  392.                 return(c);
  393.         if (c == '\n')
  394.                 if (!c_flg)
  395.                         nl();
  396.                 else
  397.                 {
  398.                         ++linum;
  399.                         ++edtnum;
  400.                 }
  401.         else
  402.                 if (!c_flg)
  403.                         if(o_flg)
  404.                                 fprintf(l_buffer,"%c",c);
  405.                         else
  406.                                 printf("%c",c);
  407.         if(rd_flg)
  408.                 return(c);
  409.         if(t_flg)
  410.         { 
  411.                 t_flg = !t_flg;
  412.                 goto rch;
  413.         }
  414.         if(c == '\\')
  415.         {
  416.                 t_flg = TRUE;
  417.                 goto rch;
  418.         }
  419.         /* 
  420.                                 If the character is not part of a quoted string
  421.                                 check for and process commented strings...
  422.                                 nested comments are handled correctly but unbalanced
  423.                                 comments are not ... the assumption is made that
  424.                                 the syntax of the program being xref'd is correct
  425.                         */
  426.  
  427.         if (!q_flg && !q1_flg) {
  428.                 if (c == '*' && c_cnt && !cs_flg) { 
  429.                         ce_flg = TRUE;
  430.                         goto rch;
  431.                 }
  432.                 if (c == '/' && ce_flg) { 
  433.                         c_cnt -= 1;
  434.                         ce_flg = FALSE;
  435.                         goto rch; 
  436.                 }
  437.                 ce_flg = FALSE;
  438.                 if (c == '/') { 
  439.                         cs_flg = TRUE;
  440.                         goto rch; 
  441.                 }
  442.                 if (c == '*' && cs_flg) { 
  443.                         c_cnt += 1;
  444.                         cs_flg = FALSE;
  445.                         goto rch; 
  446.                 }
  447.                 cs_flg = FALSE;
  448.                 if (c_cnt) goto rch;
  449.         }
  450.  
  451.         /*
  452.                                 Check for and process quoted strings
  453.                         */
  454.  
  455.         if ( c == '"' && !q1_flg) { 
  456.                 q_flg =  !q_flg; /* toggle quote flag */
  457.                 goto rch;
  458.         }
  459.         if (q_flg) goto rch;
  460.  
  461.         if (c == '\'') { 
  462.                 q1_flg = !q1_flg; /* toggle quote flag */
  463.                 goto rch; 
  464.         }
  465.         if (q1_flg) goto rch;
  466.  
  467.         /*
  468.                                 Valid character ... return to caller
  469.                         */
  470.  
  471.         return(c);
  472. }
  473.  
  474. chk_token(c_token)
  475. char    *c_token;
  476.  
  477. {
  478.         char  u_token[MAX_LEN];
  479.         int   i;
  480.  
  481.         {
  482.                 if(r_flg) return(TRUE);
  483.                 i = 0;
  484.                 do { 
  485.                         u_token[i] = toupper(c_token[i]); 
  486.                 }
  487.                 while (c_token[i++] != NULL);
  488.  
  489.                 switch(u_token[0]) {
  490.                 case 'A': 
  491.                         if (strcmp(u_token,"AUTO") == 0) return(FALSE);
  492.                         break;
  493.                 case 'B': 
  494.                         if (strcmp(u_token,"BREAK") == 0) return(FALSE);
  495.                         break;
  496.                 case 'C': 
  497.                         if (strcmp(u_token,"CHAR") == 0) return (FALSE);
  498.                         if (strcmp(u_token,"CONTINUE") == 0) return (FALSE);
  499.                         if (strcmp(u_token,"CASE") == 0) return (FALSE);
  500.                         break;
  501.                 case 'D': 
  502.                         if(strcmp(u_token,"DOUBLE") == 0) return(FALSE);
  503.                         if(strcmp(u_token,"DO") == 0) return(FALSE);
  504.                         if(strcmp(u_token,"DEFAULT") == 0) return(FALSE);
  505.                         break;
  506.                 case 'E': 
  507.                         if(strcmp(u_token,"EXTERN") == 0) return(FALSE);
  508.                         if(strcmp(u_token,"ELSE") == 0) return(FALSE);
  509.                         if(strcmp(u_token,"ENTRY") == 0) return(FALSE);
  510.                         break;
  511.                 case 'F': 
  512.                         if(strcmp(u_token,"FLOAT") == 0) return(FALSE);
  513.                         if(strcmp(u_token,"FOR") == 0) return(FALSE);
  514.                         break;
  515.                 case 'G': 
  516.                         if(strcmp(u_token,"GOTO") == 0) return(FALSE);
  517.                         break;
  518.                 case 'I': 
  519.                         if(strcmp(u_token,"INT") == 0) return(FALSE);
  520.                         if(strcmp(u_token,"IF") == 0) return(FALSE);
  521.                         break;
  522.                 case 'L': 
  523.                         if(strcmp(u_token,"LONG") == 0) return(FALSE);
  524.                         break;
  525.                 case 'R': 
  526.                         if(strcmp(u_token,"RETURN") == 0) return(FALSE);
  527.                         if(strcmp(u_token,"REGISTER") == 0) return(FALSE);
  528.                         break;
  529.                 case 'S': 
  530.                         if(strcmp(u_token,"STRUCT") == 0) return(FALSE);
  531.                         if(strcmp(u_token,"SHORT") == 0) return(FALSE);
  532.                         if(strcmp(u_token,"STATIC") == 0) return(FALSE);
  533.                         if(strcmp(u_token,"SIZEOF") == 0) return(FALSE);
  534.                         if(strcmp(u_token,"SWITCH") == 0) return(FALSE);
  535.                         break;
  536.                 case 'T': 
  537.                         if(strcmp(u_token,"TYPEDEF") == 0) return(FALSE);
  538.                         break;
  539.                 case 'U': 
  540.                         if(strcmp(u_token,"UNION") == 0) return(FALSE);
  541.                         if(strcmp(u_token,"UNSIGNED") == 0) return(FALSE);
  542.                         break;
  543.                 case 'W': 
  544.                         if(strcmp(u_token,"WHILE") == 0) return(FALSE);
  545.                         break; 
  546.                 }
  547.         }
  548.         return(TRUE);
  549. }
  550.  
  551. /*
  552.    Install parsed token and line reference in linked structure
  553. */
  554.  
  555. put_token(p_token,p_ref)
  556.  
  557. char *p_token;
  558. int  p_ref;
  559.  
  560. {
  561.         int  hsh_index;
  562.         int  i;
  563.         int  j;
  564.         int  d;
  565.         int  found;
  566.         struct id_blk *idptr;
  567.         struct rf_blk *rfptr;
  568.         struct id_blk *alloc_id();
  569.         struct rf_blk *alloc_rf();
  570.         struct rf_blk *add_rf();
  571.  
  572.         if(l_flg) return;
  573.         j=0;
  574.         for (i=0; p_token[i] != NULL; i++)  /* Hashing algorithm is far from */
  575.         {                                   /* optimal but is adequate for a */
  576.                 j = j * 10 + p_token[i];        /* memory-bound index vector!    */
  577.         }
  578.         hsh_index = abs(j) % MAX_WRD;
  579.         found = FALSE;
  580.         d = 1;
  581.         do {
  582.                 idptr = id_vector[hsh_index];
  583.                 if(idptr == NULL) {
  584.                         id_cnt++;
  585.                         idptr = id_vector[hsh_index] = alloc_id(p_token);
  586.                         chain_alpha(idptr,p_token);
  587.                         idptr->top_lnk = idptr->lst_lnk = alloc_rf(p_ref);
  588.                         found = TRUE;
  589.                 }
  590.                 else
  591.                     if(strcmp(p_token,idptr->id_name) == 0) {
  592.                         idptr->lst_lnk = add_rf(idptr->lst_lnk,p_ref);
  593.                         found = TRUE;
  594.                 }
  595.                 else
  596.                     { 
  597.                         hsh_index += d;
  598.                         d += 2;
  599.                         rhsh_cnt++;
  600.                         if (hsh_index >= MAX_WRD)
  601.                                 hsh_index -= MAX_WRD;
  602.                         if (d == MAX_WRD) {
  603.                                 printf("\nERROR: Symbol table overflow\n");
  604.                                 exit(0);
  605.                         }
  606.                 }
  607.         } 
  608.         while (!found);
  609. }
  610.  
  611. chain_alpha(ca_ptr,ca_token)
  612.  
  613. struct id_blk *ca_ptr;
  614. char  *ca_token;
  615.  
  616. {
  617.         char  c;
  618.         int   f;
  619.         struct id_blk *cur_ptr;
  620.         struct id_blk *lst_ptr;
  621.  
  622.         c = ca_token[0];
  623.         if(c == '_') c = 0;
  624.         else
  625.                 isupper(c) ? (c=1+((c-'A')*2)) : (c=2+((c-'a')*2));
  626.  
  627.         if(alpha_vector[c].alpha_top == NULL)
  628.         { 
  629.                 alpha_vector[c].alpha_top =
  630.                     alpha_vector[c].alpha_lst = ca_ptr;
  631.                 ca_ptr->alpha_lnk = NULL;
  632.                 return;
  633.         }
  634.  
  635.         /* check to see if new id_blk should be inserted between
  636.                            the alpha_vector header block and the first id_blk in
  637.                            the current alpha chain
  638.                         */
  639.  
  640.         if(strcmp(alpha_vector[c].alpha_top->id_name,ca_token) >0)
  641.         {
  642.                 ca_ptr->alpha_lnk=alpha_vector[c].alpha_top;
  643.                 alpha_vector[c].alpha_top=ca_ptr;
  644.                 return;
  645.         }
  646.  
  647.         if(strcmp(alpha_vector[c].alpha_lst->id_name,ca_token) < 0)
  648.         { 
  649.                 alpha_vector[c].alpha_lst->alpha_lnk = ca_ptr;
  650.                 ca_ptr->alpha_lnk = NULL;
  651.                 alpha_vector[c].alpha_lst=ca_ptr;
  652.                 return;
  653.         }
  654.  
  655.         cur_ptr = alpha_vector[c].alpha_top;
  656.         while(strcmp(cur_ptr->id_name,ca_token) < 0)
  657.         { 
  658.                 lst_ptr = cur_ptr;
  659.                 cur_ptr = lst_ptr->alpha_lnk;
  660.         }
  661.  
  662.         lst_ptr->alpha_lnk = ca_ptr;
  663.         ca_ptr->alpha_lnk = cur_ptr;
  664.         return;
  665. }
  666.  
  667. struct id_blk *alloc_id(aid_token)
  668. char  *aid_token;
  669.  
  670. {
  671.         int  ai;
  672.         struct id_blk *aid_ptr;
  673.  
  674.         if((aid_ptr = malloc(sizeof(oneid))) == 0)
  675.         {
  676.                 printf("\nERROR: Out of user memory\n");
  677.                 exit(0);
  678.         }
  679.         ai=0;
  680.         do {
  681.                 aid_ptr->id_name[ai] = aid_token[ai];
  682.         } 
  683.         while (aid_token[ai++] != NULL);
  684.         return (aid_ptr);
  685. }
  686.  
  687. struct rf_blk *alloc_rf(arf_ref)
  688.  
  689. int  arf_ref;
  690.  
  691. {
  692.         int ri;
  693.         struct rf_blk *arf_ptr;
  694.  
  695.         if((arf_ptr = malloc(sizeof(onerf))) == 0)
  696.         {
  697.                 printf("\nERROR: Out of user memory\n");
  698.                 exit(0);
  699.         }
  700.         arf_ptr->ref_item[0] = arf_ref;
  701.         arf_ptr->ref_cnt = 1;
  702.         for(ri=1;ri<MAX_REF;ri++)
  703.                 arf_ptr->ref_item[ri] = NULL;
  704.         return (arf_ptr);
  705. }
  706.  
  707. struct rf_blk *add_rf(adr_ptr,adr_ref)
  708.  
  709. struct rf_blk *adr_ptr;
  710. int adr_ref;
  711.  
  712. {
  713.         struct rf_blk *tmp_ptr;
  714.  
  715.         tmp_ptr = adr_ptr;
  716.         if(adr_ptr->ref_cnt == MAX_REF) {
  717.                 tmp_ptr = adr_ptr->ref_cnt = alloc_rf(adr_ref);
  718.         }
  719.         else
  720.             { 
  721.                 adr_ptr->ref_item[adr_ptr->ref_cnt++] = adr_ref;
  722.         }
  723.         return (tmp_ptr);
  724. }
  725.  
  726. prnt_tbl()
  727. {  
  728.         int prf_cnt;
  729.         int pti;
  730.         int pref;
  731.         int lin_cnt;
  732.         struct id_blk *pid_ptr;
  733.         struct rf_blk *ptb_ptr;
  734.  
  735.         prt_ref = TRUE;
  736.         prt_hdr();
  737.         for (pti=0;pti<MAX_ALPHA;pti++)
  738.         { 
  739.                 if ((pid_ptr = alpha_vector[pti].alpha_top) != NULL)
  740.                 { 
  741.                         do
  742.                             { 
  743.                                 if(o_flg)
  744.                                 {
  745.                                         fprintf(l_buffer,"%-14.13s: ",pid_ptr->id_name);
  746.                                 }
  747.                                 else
  748.                                     printf("%-14.13s: ",pid_ptr->id_name);
  749.                                 ptb_ptr=pid_ptr->top_lnk;
  750.                                 lin_cnt=prf_cnt=0;
  751.                                 do { 
  752.                                         if(prf_cnt == MAX_REF)
  753.                                         { 
  754.                                                 prf_cnt=0;
  755.                                                 ptb_ptr = ptb_ptr->ref_cnt;
  756.                                         }
  757.                                         if(ptb_ptr > MAX_REF)
  758.                                         {
  759.                                                 if((pref=ptb_ptr->ref_item[prf_cnt++]) != 0)
  760.                                                 { 
  761.                                                         if(o_flg)
  762.                                                         {
  763.                                                                 fprintf(l_buffer,"%d\t",pref);
  764.                                                         }
  765.                                                         else
  766.                                                             printf("%d\t",pref);
  767.                                                         if (++lin_cnt == REFS_PER_LINE)
  768.                                                         { 
  769.                                                                 nl();
  770.                                                                 if(o_flg)
  771.                                                                 {
  772.                                                                         fprintf(l_buffer,"\t\t");
  773.                                                                 }
  774.                                                                 else
  775.                                                                     printf("\t\t");
  776.                                                                 lin_cnt=0;
  777.                                                         }
  778.                                                 }
  779.                                         } 
  780.                                         else pref=0;
  781.                                 } 
  782.                                 while (pref);
  783.                                 if (lin_cnt = 0)
  784.                                         nl();
  785.                                 else
  786.                                 { 
  787.                                         nl(); 
  788.                                         nl(); 
  789.                                 }
  790.                         } 
  791.                         while ((pid_ptr=pid_ptr->alpha_lnk) != NULL);
  792.                 }
  793.         }
  794. }
  795.  
  796. prt_hdr()
  797.  
  798.         if (pagno++ != 0)
  799.                 if (o_flg)
  800.                         fprintf(l_buffer,"%c",FF);
  801.                 else
  802.                         printf("%c",FF);
  803.         if (o_flg)
  804.                 fprintf (l_buffer, "'C' Cross Reference Utility  -  File: %s\t\t\t\t Page %d", gbl_fil, pagno);
  805.         else
  806.                 printf ("'C' Cross Reference Utility  -  File: %s\t\t\t\t Page %d", gbl_fil, pagno);
  807.         if (o_flg)
  808.                 fprintf(l_buffer,"\n\n");
  809.         else
  810.                 printf("\n\n");
  811.         if (!c_flg)
  812.                 nl();
  813.         paglin =3;
  814.         return;
  815. }
  816.  
  817.  
  818. /***************************************************************************
  819.  * do end of input file line stuff
  820.  */
  821.  
  822. nl()
  823.         if (o_flg)
  824.                 fprintf(l_buffer,"\n");
  825.         else
  826.                 printf("\n");
  827.         if (++paglin == paglen)
  828.                 prt_hdr();
  829.         else
  830.                 if (!prt_ref)
  831.                 {
  832.                         if (o_flg)
  833.                                 fprintf(l_buffer,"%-4.4d.%4.4d:\t",++linum,++edtnum);
  834.                         else
  835.                                 printf("%-4.4d.%4.4d:\t",++linum,++edtnum);
  836.                         if (o_flg) 
  837.                                 if(linum % 60 == 1) 
  838.                                         printf("\n<%d>\t",linum);
  839.                         else
  840.                             printf(".");
  841.                 }
  842.         return;
  843. }
  844.  
  845.  
  846. /*      atoi:   ascii string to integer
  847.  * This is too inconsistant to use the system's
  848.  */
  849.  
  850. atoi(st)
  851.  
  852. char *st;
  853.  
  854. {
  855.         int result;     /* resulting number */
  856.         int sign;       /* sign of resulting number */
  857.         char c;         /* current char being examined */
  858.  
  859.         result = 0;
  860.         sign = 1;
  861.  
  862.         /* skip preceding whitespace */
  863.         while (*st == ' ' || *st == '\t')
  864.                 ++st;
  865.  
  866.         /* check for sign */
  867.         if (*st == '-') {
  868.                 sign = -1;
  869.                 ++st;
  870.         }
  871.         if (*st == '+')
  872.                 ++st;
  873.  
  874.         /* scan digits, build value */
  875.         while ((c = *st++))
  876.                 if (c >= '0' && c <= '9')
  877.                         result = result * 10 + c - '0';
  878.                 else
  879.                         return(0);
  880.  
  881.         return(result * sign);
  882. }
  883.